home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / gkismet / Connection.pm < prev    next >
Text File  |  2005-10-20  |  9KB  |  456 lines

  1. #!/usr/bin/perl -w
  2. #
  3. # $Id: Connection.pm,v 1.33 2004/11/26 08:41:42 solovam Exp $
  4. #
  5. # This file is a part of gkismet
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU General Public License
  9. # as published by the Free Software Foundation; either version 2
  10. # of the License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20. #
  21.  
  22. #
  23. # Connection class
  24. #
  25. package Connection;
  26.  
  27. use IO::Socket;
  28. use IO::Select;
  29. use Gtk;
  30. use Misc;
  31. use Observable;
  32. use strict;
  33.  
  34. my $timeout = 5;
  35.  
  36. #
  37. # Inherit methods from Observable
  38. #
  39. @Connection::ISA = qw(Observable);
  40.  
  41. #
  42. # Constructor
  43. #
  44. sub new
  45. {
  46.     # Standard prologue
  47.     my $type = shift;
  48.     my $self = {};
  49.     bless $self, $type;
  50.  
  51.     # Constructor arguments
  52.     $self->{'gKismetApplication'} = shift;
  53.     $self->{'host'} = shift;
  54.     $self->{'port'} = shift;
  55.  
  56.     # Connect to server
  57.     if(!$self->connect())
  58.     {
  59.         return(undef);
  60.     }
  61.  
  62.     # Enable protocols
  63.     $self->enableProtocols();
  64.  
  65.     # Init fields
  66.     $self->{'network'} = {};
  67.     $self->{'status'} = {};
  68.     $self->{'info'} = {};
  69.     $self->{'packet'} = {};
  70.     $self->{'string'} = {};
  71.     $self->{'gps'} = {};
  72.     $self->{'time'} = {};
  73.     $self->{'alert'} = {};
  74.  
  75.     return($self);
  76. }
  77.  
  78. #
  79. # Destructor
  80. #
  81. sub DESTROY
  82. {
  83.     my $self = shift;
  84.     $self->disconnect();
  85. }
  86.  
  87. #
  88. # Get socket
  89. #
  90. sub getSocket
  91. {
  92.     my $self = shift;
  93.     return $self->{'socket'};
  94. }
  95.  
  96. #
  97. # Connect to server
  98. #
  99. sub connect
  100. {
  101.     my $self = shift;
  102.  
  103.     $self->{'socket'} = IO::Socket::INET->new("PeerAddr" => $self->{'host'}, "PeerPort" => $self->{'port'}, "Proto" => "tcp", "Timeout" => $timeout);
  104.     unless($self->{'socket'})
  105.     {
  106.         return(0);
  107.     }
  108.  
  109.     # Register input handler
  110.     my $inputId = Gtk::Gdk->input_add($self->getSocket()->fileno, 'read', sub {$self->readServer()}, $self->getSocket());
  111.     $self->{'inputId'} = $inputId;
  112.  
  113.     # Is it a kismet server we connected to?
  114.     unless($self->{'socket'}->getline() =~ /\*KISMET/)
  115.     {
  116.         $self->disconnect();
  117.         return(0);
  118.     }
  119.  
  120.     return(1);
  121. }
  122.  
  123. #
  124. # Disconnect from server
  125. #
  126. sub disconnect
  127. {
  128.     my $self = shift;
  129.     if(defined $self->{'inputId'})
  130.     {
  131.         Gtk::Gdk->input_remove($self->{'inputId'});
  132.     }
  133.     if($self->{'socket'})
  134.     {
  135.         $self->{'socket'}->close();
  136.     }
  137. }
  138.  
  139. #
  140. # Enable default set of protocols to watch
  141. #
  142. sub enableProtocols
  143. {
  144.     my $self = shift;
  145.     my @protocols = qw(GPS INFO NETWORK CLIENT REMOVE ALERT STATUS);
  146.     for my $p (@protocols)
  147.     {
  148.         $self->{'socket'}->print("!0 ENABLE $p *\n");
  149.     }
  150. }
  151.  
  152. #
  153. # Eanble strings
  154. #
  155. sub enableStrings
  156. {
  157.     my $self = shift;
  158.     $self->{'socket'}->print("!0 ENABLE STRING *\n");
  159. }
  160.  
  161. #
  162. # Disable strings
  163. #
  164. sub disableStrings
  165. {
  166.     my $self = shift;
  167.     $self->{'socket'}->print("!0 REMOVE STRING\n");
  168. }
  169.  
  170. #
  171. # Enable packets
  172. #
  173. sub enablePackets
  174. {
  175.     my $self = shift;
  176.     $self->{'socket'}->print("!0 ENABLE PACKET *\n");
  177. }
  178.  
  179. #
  180. # Disable packets
  181. #
  182. sub disablePackets
  183. {
  184.     my $self = shift;
  185.     $self->{'socket'}->print("!0 REMOVE PACKET\n");
  186. }
  187.  
  188. #
  189. # Ask server to print capabilities
  190. #
  191. sub askCaps
  192. {
  193.     my $self = shift;
  194.     my @protocols = qw(GPS INFO NETWORK CLIENT REMOVE ALERT STATUS STRING PACKET);
  195.     for my $p (@protocols)
  196.     {
  197.         $self->{'socket'}->print("!0 CAPABILITY $p\n");
  198.     }
  199. }
  200.  
  201. #
  202. # Read and parse input
  203. #
  204. my $inReadServer = $false;
  205. sub readServer 
  206. {
  207.     my $self = shift;
  208.  
  209.     if($inReadServer)
  210.     {
  211.         return;
  212.     }
  213.     $inReadServer = $true;
  214.  
  215.     my $res = $self->{'socket'}->getline();
  216.     if(!$res)
  217.     {
  218.         $self->notifyObservers({'changed' => 'disconnected'});
  219.     }
  220.     else
  221.     {
  222.         chomp($res);
  223.         my($cmd, $data) = ($res =~ /\*([^:]+):\s+(.*)/);
  224.  
  225.         if($cmd eq 'GPS')
  226.         {
  227.             my @fields = qw(lat lon alt spd heading fix);
  228.             my @values = Connection->oneSplit($data);
  229.             $self->{'gps'} = Connection->makeHash(\@fields, \@values);
  230.             $self->notifyObservers({'changed' => 'gps'});
  231.         }
  232.         elsif($cmd eq 'INFO')
  233.         {
  234.             my @fields = qw(networks packets crypt weak noise dropped rate cardquality  cardpower cardnoise);
  235.             my @values = Connection->oneSplit($data);
  236.             $self->{'info'} = Connection->makeHash(\@fields, \@values);
  237.             $self->notifyObservers({'changed' => 'info'});
  238.         }
  239.         elsif($cmd eq 'NETWORK')
  240.         {
  241.             my @fields = qw(bssid type ssid beaconinfo llcpackets datapackets cryptpackets weakpackets channel wep firsttime lasttime atype
  242.                 rangeip gpsfixed minlat minlon minalt minspd maxlat maxlon maxalt maxspd octets cloaked beaconrate maxrate
  243.                 manufkey manufscore quality signal noise bestquality bestsignal bestnoise bestlat bestlon bestalt agglat agglon
  244.                 aggalt aggpoints datasize turbocellnid turbocellmode turbocellsat carrierset maxseenrate encodingset decrypted dupeivpackets);
  245.             my @values = Connection->oneSplit($data);
  246.             my $bssid = $values[0];
  247.             for(my $i = 0; $i <= $#fields; $i++)
  248.             {
  249.                 $self->{'network'}{$bssid}{$fields[$i]} = defined $values[$i] ? $values[$i] : 0;
  250.             }
  251.             $self->notifyObservers({'changed' => 'network', 'bssid' => $bssid});
  252.         }
  253.         elsif($cmd eq 'CLIENT')
  254.         {
  255.             my @fields = qw(bssid mac type firsttime lasttime manufkey manufscore datapackets cryptpackets weakpackets gpsfixed minlat minlon
  256.                 minalt minspd maxlat maxlon maxalt maxspd agglat agglon aggalt aggpoints maxrate quality signal noise bestquality
  257.                 bestsignal bestnoise bestlat bestlon bestalt atype ip datasize maxseenrate encodingset decrypted);
  258.             my @values = Connection->oneSplit($data);
  259.             my($bssid, $mac) = @values[0,1];
  260.             for(my $i = 0; $i <= $#fields; $i++)
  261.             {
  262.                 $self->{'network'}{$bssid}{'client'}{$mac}{$fields[$i]} = defined $values[$i] ? $values[$i] : 0;
  263.             }
  264.             $self->notifyObservers({'changed' => 'client', 'bssid' => $bssid, 'mac' => $mac});
  265.         }
  266.         elsif($cmd eq 'REMOVE')
  267.         {
  268.             my $bssid = $data;
  269.             if(defined $self->{'network'}{$bssid})
  270.             {
  271.                 $self->notifyObservers({'changed' => 'remove', 'bssid' => $bssid});
  272.                 delete $self->{'network'}{$bssid};
  273.             }
  274.         }
  275.         elsif($cmd eq 'ALERT')
  276.         {
  277.             my @fields = qw(sec usec header bssid source dest other channel text);
  278.             my @values = Connection->oneSplit($data);
  279.             $self->{'alert'} = Connection->makeHash(\@fields, \@values);
  280.             $self->notifyObservers({'changed' => 'alert'});
  281.         }
  282.         elsif($cmd eq 'STATUS')
  283.         {
  284.             $self->{'status'} = $data;
  285.             $self->notifyObservers({'changed' => 'status'});
  286.         }
  287.         elsif($cmd eq 'TIME')
  288.         {
  289.             $self->{'time'} = $data;
  290.             $self->notifyObservers({'changed' => 'time'});
  291.         }
  292.         elsif($cmd eq 'PACKET')
  293.         {
  294.             # Should we kep more than one packet?
  295.             my @fields = qw(type subtype timesec encrypted weak beaconrate sourcemac destmac bssid ssid prototype sourceip destip sourceport
  296.                 destport nbtype nbsource);
  297.             my @values = Connection->oneSplit($data);
  298.             $self->{'packet'} = Connection->makeHash(\@fields, \@values);
  299.             $self->notifyObservers({'changed' => 'packet'});
  300.         }
  301.         elsif($cmd eq 'STRING')
  302.         {
  303.             # Should we kep more than one string?
  304.             my @fields = qw(bssid sourcemac text);
  305.             my @values = Connection->oneSplit($data);
  306.             $self->{'string'} = Connection->makeHash(\@fields, \@values);
  307.             $self->notifyObservers({'changed' => 'string'});
  308.         }
  309.     }
  310.     $inReadServer = $false;
  311. }
  312.  
  313. #
  314. # Make hash from an array of keys and values 
  315. #
  316. sub makeHash
  317. {
  318.     shift;
  319.     my $keys = shift;
  320.     my $values = shift;
  321.     my %hash;
  322.     for(my $i = 0; $i <= $#{$keys}; $i++)
  323.     {
  324.             $hash{$keys->[$i]} = defined $values->[$i] ? $values->[$i] : 0;
  325.     }
  326.     return \%hash;
  327. }
  328.  
  329. #
  330. # Get port
  331. #
  332. sub port
  333. {
  334.     my $self = shift;
  335.     return $self->{'port'};
  336. }
  337.  
  338. #
  339. # Get host
  340. #
  341. sub host
  342. {
  343.     my $self = shift;
  344.     return $self->{'host'};
  345. }
  346.  
  347. #
  348. # Get network
  349. #
  350. sub getNetwork
  351. {
  352.     my $self = shift;
  353.     return $self->{'network'};
  354. }
  355.  
  356. #
  357. # get status
  358. #
  359. sub getStatus
  360. {
  361.     my $self = shift;
  362.     return $self->{'status'};
  363. }
  364.  
  365. #
  366. # Get info
  367. #
  368. sub getInfo
  369. {
  370.     my $self = shift;
  371.     return $self->{'info'};
  372. }
  373.  
  374. #
  375. # Get GPS
  376. #
  377. sub getGps
  378. {
  379.     my $self = shift;
  380.     return $self->{'gps'};
  381. }
  382.  
  383. #
  384. # Get alert
  385. #
  386. sub getAlert
  387. {
  388.     my $self = shift;
  389.     return $self->{'alert'};
  390. }
  391.  
  392. #
  393. # Get time
  394. #
  395. sub getTime
  396. {
  397.     my $self = shift;
  398.     return $self->{'time'};
  399. }
  400.  
  401. #
  402. # Get string
  403. #
  404. sub getString
  405. {
  406.     my $self = shift;
  407.     return $self->{'string'};
  408. }
  409.  
  410. #
  411. # Get packet
  412. #
  413. sub getPacket
  414. {
  415.     my $self = shift;
  416.     return $self->{'packet'};
  417. }
  418.  
  419. #
  420. # Split on space. \001 works as quotation symbol. Based on shellwords.pl
  421. #
  422. sub oneSplit
  423. {
  424.     shift;
  425.  
  426.     ($_) = (@_);
  427.     my(@words, $snippet, $field);
  428.  
  429.     s/^\s+//;
  430.     while ($_ ne '')
  431.     {
  432.         $field = '';
  433.         while(1)
  434.         {
  435.             if(s/^\001([^\001]*)\001//)
  436.             {
  437.                 $snippet = $1;
  438.             }
  439.             elsif(s/^([^\s\001]+)//)
  440.             {
  441.                 $snippet = $1;
  442.             }
  443.             else
  444.             {
  445.                 s/^\s+//;
  446.                 last;
  447.             }
  448.             $field .= $snippet;
  449.         }
  450.         push(@words, $field);
  451.     }
  452.     return(@words);
  453. }
  454.  
  455. 1;
  456.